using Microsoft.Extensions.Logging;
using System.Diagnostics;
using System.Management;
using DocumentCreationSystem.Models;
using System.IO;

namespace DocumentCreationSystem.Services;

/// <summary>
/// 系统监控服务实现
/// </summary>
public class SystemMonitorService : ISystemMonitorService, IDisposable
{
    private readonly ILogger<SystemMonitorService> _logger;
    private readonly IAIService _aiService;
    private readonly IAIModelConfigService _configService;
    private readonly Timer _monitorTimer;
    private readonly PerformanceCounter _cpuCounter;
    private readonly PerformanceCounter _memoryCounter;
    private bool _isMonitoring = false;
    private bool _disposed = false;

    public event EventHandler<SystemMonitorEventArgs>? MonitorDataUpdated;

    public SystemMonitorService(
        ILogger<SystemMonitorService> logger,
        IAIService aiService,
        IAIModelConfigService configService)
    {
        _logger = logger;
        _aiService = aiService;
        _configService = configService;

        // 初始化性能计数器
        try
        {
            _cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
            _memoryCounter = new PerformanceCounter("Memory", "Available MBytes");
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "无法初始化性能计数器，将使用备用方法");
            _cpuCounter = null!;
            _memoryCounter = null!;
        }

        // 创建定时器，每5秒更新一次
        _monitorTimer = new Timer(UpdateMonitorData, null, Timeout.Infinite, Timeout.Infinite);
    }

    public async Task<CurrentModelInfo> GetCurrentModelInfoAsync()
    {
        try
        {
            var config = await _configService.GetConfigAsync();
            var currentModel = _aiService.GetCurrentModel();

            // 确保平台信息准确
            var actualPlatform = config.Platform ?? "未知平台";
            var modelName = "未选择模型";
            var isAvailable = false;

            // 优先使用当前模型的信息
            if (currentModel != null)
            {
                modelName = currentModel.Name ?? currentModel.Id ?? "未知模型";
                if (!string.IsNullOrEmpty(currentModel.Provider))
                {
                    actualPlatform = currentModel.Provider;
                }
                isAvailable = true;
            }
            else
            {
                // 如果没有当前模型，尝试从配置中获取选中的模型名称
                var selectedModel = GetSelectedModelFromConfig(config);
                if (!string.IsNullOrEmpty(selectedModel))
                {
                    modelName = selectedModel;
                    isAvailable = false; // 配置中的模型但当前不可用
                }
            }

            return new CurrentModelInfo
            {
                Platform = actualPlatform,
                ModelName = modelName,
                Status = isAvailable ? "在线" : "离线",
                IsAvailable = isAvailable,
                LastUpdated = DateTime.Now
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取当前模型信息失败");
            return new CurrentModelInfo
            {
                Platform = "未知",
                ModelName = "获取失败",
                Status = "错误",
                IsAvailable = false,
                LastUpdated = DateTime.Now
            };
        }
    }

    private string GetSelectedModelFromConfig(AIModelConfig config)
    {
        return config.Platform switch
        {
            "Ollama" => config.OllamaConfig?.SelectedModel ?? "",
            "LMStudio" => config.LMStudioConfig?.SelectedModel ?? "",
            "ZhipuAI" => config.ZhipuAIConfig?.Model ?? "",
            "DeepSeek" => config.DeepSeekConfig?.Model ?? "",
            _ => ""
        };
    }

    public async Task<SystemResourceInfo> GetSystemResourceInfoAsync()
    {
        var cpuInfo = await GetCpuInfoAsync();
        var memoryInfo = await GetMemoryInfoAsync();
        var gpuInfo = await GetGpuInfoAsync();

        return new SystemResourceInfo
        {
            Cpu = cpuInfo,
            Memory = memoryInfo,
            Gpu = gpuInfo,
            LastUpdated = DateTime.Now
        };
    }

    public async Task<CpuInfo> GetCpuInfoAsync()
    {
        try
        {
            var cpuInfo = new CpuInfo
            {
                CoreCount = Environment.ProcessorCount
            };

            // 获取CPU使用率
            if (_cpuCounter != null)
            {
                try
                {
                    cpuInfo.UsagePercentage = Math.Round(_cpuCounter.NextValue(), 1);
                }
                catch
                {
                    // 如果性能计数器失败，使用进程信息估算
                    cpuInfo.UsagePercentage = await GetCpuUsageFallback();
                }
            }
            else
            {
                cpuInfo.UsagePercentage = await GetCpuUsageFallback();
            }

            // 获取CPU名称
            try
            {
                using var searcher = new ManagementObjectSearcher("SELECT Name FROM Win32_Processor");
                foreach (ManagementObject obj in searcher.Get())
                {
                    cpuInfo.Name = obj["Name"]?.ToString() ?? "未知";
                    break;
                }
            }
            catch (Exception ex)
            {
                _logger.LogDebug(ex, "无法获取CPU名称");
                cpuInfo.Name = "未知";
            }

            return cpuInfo;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取CPU信息失败");
            return new CpuInfo { Name = "获取失败" };
        }
    }

    public async Task<MemoryInfo> GetMemoryInfoAsync()
    {
        try
        {
            var memoryInfo = new MemoryInfo();

            // 获取系统内存信息
            var totalMemory = GC.GetTotalMemory(false);
            var process = Process.GetCurrentProcess();
            memoryInfo.ProcessMemoryMB = process.WorkingSet64 / 1024 / 1024;

            // 获取系统总内存
            try
            {
                using var searcher = new ManagementObjectSearcher("SELECT TotalPhysicalMemory FROM Win32_ComputerSystem");
                foreach (ManagementObject obj in searcher.Get())
                {
                    var totalPhysical = Convert.ToInt64(obj["TotalPhysicalMemory"]);
                    memoryInfo.TotalMemoryMB = totalPhysical / 1024 / 1024;
                    break;
                }
            }
            catch (Exception ex)
            {
                _logger.LogDebug(ex, "无法获取系统总内存");
                memoryInfo.TotalMemoryMB = 8192; // 默认8GB
            }

            // 获取可用内存
            if (_memoryCounter != null)
            {
                try
                {
                    memoryInfo.AvailableMemoryMB = (long)_memoryCounter.NextValue();
                }
                catch
                {
                    memoryInfo.AvailableMemoryMB = memoryInfo.TotalMemoryMB / 2; // 估算
                }
            }
            else
            {
                memoryInfo.AvailableMemoryMB = memoryInfo.TotalMemoryMB / 2; // 估算
            }

            memoryInfo.UsedMemoryMB = memoryInfo.TotalMemoryMB - memoryInfo.AvailableMemoryMB;
            memoryInfo.UsagePercentage = memoryInfo.TotalMemoryMB > 0 
                ? Math.Round((double)memoryInfo.UsedMemoryMB / memoryInfo.TotalMemoryMB * 100, 1)
                : 0.0;

            return memoryInfo;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取内存信息失败");
            return new MemoryInfo();
        }
    }

    public async Task<GpuInfo> GetGpuInfoAsync()
    {
        try
        {
            var gpuInfo = new GpuInfo();

            // 获取GPU基本信息
            await GetGpuBasicInfoAsync(gpuInfo);

            // 获取GPU使用率和显存信息
            if (gpuInfo.IsAvailable)
            {
                await GetGpuPerformanceInfoAsync(gpuInfo);
            }

            return gpuInfo;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取GPU信息失败");
            return new GpuInfo();
        }
    }

    /// <summary>
    /// 获取GPU基本信息（名称、驱动版本等）
    /// </summary>
    private async Task GetGpuBasicInfoAsync(GpuInfo gpuInfo)
    {
        try
        {
            using var searcher = new ManagementObjectSearcher("SELECT Name, DriverVersion, AdapterRAM FROM Win32_VideoController");
            foreach (ManagementObject obj in searcher.Get())
            {
                var name = obj["Name"]?.ToString();
                if (!string.IsNullOrEmpty(name) && !name.Contains("Microsoft Basic"))
                {
                    gpuInfo.Name = name;
                    gpuInfo.DriverVersion = obj["DriverVersion"]?.ToString() ?? "未知";
                    gpuInfo.IsAvailable = true;

                    // 获取GPU显存总量
                    if (obj["AdapterRAM"] != null && uint.TryParse(obj["AdapterRAM"].ToString(), out uint adapterRAM))
                    {
                        gpuInfo.TotalMemoryMB = adapterRAM / 1024 / 1024; // 转换为MB
                    }
                    break;
                }
            }
        }
        catch (Exception ex)
        {
            _logger.LogDebug(ex, "无法获取GPU基本信息");
        }
    }

    /// <summary>
    /// 获取GPU性能信息（使用率、显存占用等）
    /// </summary>
    private async Task GetGpuPerformanceInfoAsync(GpuInfo gpuInfo)
    {
        try
        {
            // 尝试多种方法获取GPU使用率
            var gpuUsage = await GetGpuUsagePercentageAsync();
            if (gpuUsage.HasValue)
            {
                gpuInfo.UsagePercentage = Math.Round(gpuUsage.Value, 1);
            }

            // 获取GPU显存使用情况
            var memoryInfo = await GetGpuMemoryUsageAsync();
            if (memoryInfo.HasValue)
            {
                gpuInfo.UsedMemoryMB = memoryInfo.Value;
            }

            // 尝试获取GPU温度
            var temperature = await GetGpuTemperatureAsync();
            if (temperature.HasValue)
            {
                gpuInfo.Temperature = Math.Round(temperature.Value, 1);
            }
        }
        catch (Exception ex)
        {
            _logger.LogDebug(ex, "无法获取GPU性能信息");
        }
    }

    /// <summary>
    /// 获取GPU使用率百分比
    /// </summary>
    private async Task<double?> GetGpuUsagePercentageAsync()
    {
        try
        {
            // 方法1：尝试使用性能计数器（适用于NVIDIA GPU）
            try
            {
                using var gpuCounter = new PerformanceCounter("GPU Engine", "Utilization Percentage", "_Total");
                var usage = gpuCounter.NextValue();
                if (usage > 0)
                {
                    return usage;
                }
            }
            catch
            {
                // 性能计数器可能不可用，继续尝试其他方法
            }

            // 方法2：通过nvidia-smi命令获取（适用于NVIDIA GPU）
            var nvidiaUsage = await GetNvidiaGpuUsageAsync();
            if (nvidiaUsage.HasValue)
            {
                return nvidiaUsage.Value;
            }

            return null;
        }
        catch (Exception ex)
        {
            _logger.LogDebug(ex, "获取GPU使用率失败");
            return null;
        }
    }

    /// <summary>
    /// 通过nvidia-smi获取NVIDIA GPU使用率
    /// </summary>
    private async Task<double?> GetNvidiaGpuUsageAsync()
    {
        try
        {
            var processInfo = new ProcessStartInfo
            {
                FileName = "nvidia-smi",
                Arguments = "--query-gpu=utilization.gpu --format=csv,noheader,nounits",
                UseShellExecute = false,
                RedirectStandardOutput = true,
                CreateNoWindow = true
            };

            using var process = Process.Start(processInfo);
            if (process != null)
            {
                var output = await process.StandardOutput.ReadToEndAsync();
                await process.WaitForExitAsync();

                if (process.ExitCode == 0 && double.TryParse(output.Trim(), out double usage))
                {
                    return usage;
                }
            }
        }
        catch (Exception ex)
        {
            _logger.LogDebug(ex, "nvidia-smi命令执行失败");
        }

        return null;
    }

    /// <summary>
    /// 获取GPU显存使用量
    /// </summary>
    private async Task<long?> GetGpuMemoryUsageAsync()
    {
        try
        {
            // 通过nvidia-smi获取显存使用情况（适用于NVIDIA GPU）
            var nvidiaMemory = await GetNvidiaGpuMemoryUsageAsync();
            if (nvidiaMemory.HasValue)
            {
                return nvidiaMemory.Value;
            }

            // 对于其他GPU，可以尝试其他方法
            return null;
        }
        catch (Exception ex)
        {
            _logger.LogDebug(ex, "获取GPU显存使用量失败");
            return null;
        }
    }

    /// <summary>
    /// 通过nvidia-smi获取NVIDIA GPU显存使用量
    /// </summary>
    private async Task<long?> GetNvidiaGpuMemoryUsageAsync()
    {
        try
        {
            var processInfo = new ProcessStartInfo
            {
                FileName = "nvidia-smi",
                Arguments = "--query-gpu=memory.used --format=csv,noheader,nounits",
                UseShellExecute = false,
                RedirectStandardOutput = true,
                CreateNoWindow = true
            };

            using var process = Process.Start(processInfo);
            if (process != null)
            {
                var output = await process.StandardOutput.ReadToEndAsync();
                await process.WaitForExitAsync();

                if (process.ExitCode == 0 && long.TryParse(output.Trim(), out long memoryUsed))
                {
                    return memoryUsed; // nvidia-smi返回的是MB
                }
            }
        }
        catch (Exception ex)
        {
            _logger.LogDebug(ex, "nvidia-smi显存查询失败");
        }

        return null;
    }

    /// <summary>
    /// 获取GPU温度
    /// </summary>
    private async Task<double?> GetGpuTemperatureAsync()
    {
        try
        {
            // 通过nvidia-smi获取GPU温度（适用于NVIDIA GPU）
            var nvidiaTemperature = await GetNvidiaGpuTemperatureAsync();
            if (nvidiaTemperature.HasValue)
            {
                return nvidiaTemperature.Value;
            }

            return null;
        }
        catch (Exception ex)
        {
            _logger.LogDebug(ex, "获取GPU温度失败");
            return null;
        }
    }

    /// <summary>
    /// 通过nvidia-smi获取NVIDIA GPU温度
    /// </summary>
    private async Task<double?> GetNvidiaGpuTemperatureAsync()
    {
        try
        {
            var processInfo = new ProcessStartInfo
            {
                FileName = "nvidia-smi",
                Arguments = "--query-gpu=temperature.gpu --format=csv,noheader,nounits",
                UseShellExecute = false,
                RedirectStandardOutput = true,
                CreateNoWindow = true
            };

            using var process = Process.Start(processInfo);
            if (process != null)
            {
                var output = await process.StandardOutput.ReadToEndAsync();
                await process.WaitForExitAsync();

                if (process.ExitCode == 0 && double.TryParse(output.Trim(), out double temperature))
                {
                    return temperature;
                }
            }
        }
        catch (Exception ex)
        {
            _logger.LogDebug(ex, "nvidia-smi温度查询失败");
        }

        return null;
    }

    public void StartMonitoring()
    {
        if (!_isMonitoring)
        {
            _isMonitoring = true;
            _monitorTimer.Change(TimeSpan.Zero, TimeSpan.FromSeconds(5));
            _logger.LogInformation("系统监控已启动");
        }
    }

    public void StopMonitoring()
    {
        if (_isMonitoring)
        {
            _isMonitoring = false;
            _monitorTimer.Change(Timeout.Infinite, Timeout.Infinite);
            _logger.LogInformation("系统监控已停止");
        }
    }

    private async void UpdateMonitorData(object? state)
    {
        if (!_isMonitoring) return;

        try
        {
            var modelInfo = await GetCurrentModelInfoAsync();
            var resourceInfo = await GetSystemResourceInfoAsync();

            MonitorDataUpdated?.Invoke(this, new SystemMonitorEventArgs
            {
                ModelInfo = modelInfo,
                ResourceInfo = resourceInfo,
                UpdateTime = DateTime.Now
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "更新监控数据失败");
        }
    }

    private async Task<double> GetCpuUsageFallback()
    {
        // 简单的CPU使用率估算
        var startTime = DateTime.UtcNow;
        var startCpuUsage = Process.GetCurrentProcess().TotalProcessorTime;
        
        await Task.Delay(100);
        
        var endTime = DateTime.UtcNow;
        var endCpuUsage = Process.GetCurrentProcess().TotalProcessorTime;
        
        var cpuUsedMs = (endCpuUsage - startCpuUsage).TotalMilliseconds;
        var totalMsPassed = (endTime - startTime).TotalMilliseconds;
        var cpuUsageTotal = cpuUsedMs / (Environment.ProcessorCount * totalMsPassed);
        
        return Math.Round(cpuUsageTotal * 100, 1);
    }

    /// <summary>
    /// 获取系统指标
    /// </summary>
    public async Task<SystemMetrics> GetSystemMetricsAsync()
    {
        try
        {
            var metrics = new SystemMetrics();

            // 获取各项指标
            metrics.CpuUsage = await GetCpuUsageAsync();
            metrics.MemoryUsage = await GetMemoryUsageAsync();
            metrics.DiskUsage = await GetDiskUsageAsync();
            metrics.NetworkUsage = await GetNetworkUsageAsync();
            metrics.GpuUsage = await GetGpuUsageAsync();
            var gpuMemoryUsage = await GetGpuMemoryUsageAsync();
            metrics.GpuMemoryUsage = gpuMemoryUsage.HasValue ? (float)gpuMemoryUsage.Value : 0f;

            // 获取内存信息
            var memoryInfo = await GetMemoryInfoAsync();
            metrics.TotalMemory = memoryInfo.Total;
            metrics.AvailableMemory = memoryInfo.Available;

            // 获取磁盘信息
            var diskInfo = await GetDiskInfoAsync();
            metrics.TotalDiskSpace = diskInfo.Total;
            metrics.AvailableDiskSpace = diskInfo.Available;

            // 获取进程信息
            metrics.ProcessCount = Process.GetProcesses().Length;
            metrics.ThreadCount = Process.GetCurrentProcess().Threads.Count;

            return metrics;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取系统指标失败");
            return new SystemMetrics();
        }
    }

    /// <summary>
    /// 获取CPU使用率
    /// </summary>
    public async Task<float> GetCpuUsageAsync()
    {
        try
        {
            if (_cpuCounter != null)
            {
                // 第一次调用返回0，需要等待一段时间
                _cpuCounter.NextValue();
                await Task.Delay(100);
                return _cpuCounter.NextValue();
            }

            // 替代方法：使用Process类
            var startTime = DateTime.UtcNow;
            var startCpuUsage = Process.GetCurrentProcess().TotalProcessorTime;
            await Task.Delay(500);

            var endTime = DateTime.UtcNow;
            var endCpuUsage = Process.GetCurrentProcess().TotalProcessorTime;

            var cpuUsedMs = (endCpuUsage - startCpuUsage).TotalMilliseconds;
            var totalMsPassed = (endTime - startTime).TotalMilliseconds;
            var cpuUsageTotal = cpuUsedMs / (Environment.ProcessorCount * totalMsPassed);

            return (float)(cpuUsageTotal * 100);
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "获取CPU使用率失败");
            return 0f;
        }
    }

    /// <summary>
    /// 获取内存使用率
    /// </summary>
    public async Task<float> GetMemoryUsageAsync()
    {
        try
        {
            var memoryInfo = await GetMemoryInfoAsync();
            if (memoryInfo.Total > 0)
            {
                var usedMemory = memoryInfo.Total - memoryInfo.Available;
                return (float)(usedMemory * 100.0 / memoryInfo.Total);
            }

            return 0f;
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "获取内存使用率失败");
            return 0f;
        }
    }

    /// <summary>
    /// 获取GPU使用率
    /// </summary>
    public async Task<float> GetGpuUsageAsync()
    {
        try
        {
            // 简化实现，返回模拟值
            await Task.Delay(1);
            return 0f;
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "获取GPU使用率失败");
            return 0f;
        }
    }

    /// <summary>
    /// 获取磁盘使用率
    /// </summary>
    public async Task<float> GetDiskUsageAsync()
    {
        try
        {
            var diskInfo = await GetDiskInfoAsync();
            if (diskInfo.Total > 0)
            {
                var usedSpace = diskInfo.Total - diskInfo.Available;
                return (float)(usedSpace * 100.0 / diskInfo.Total);
            }

            return 0f;
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "获取磁盘使用率失败");
            return 0f;
        }
    }

    /// <summary>
    /// 获取网络使用率
    /// </summary>
    public async Task<float> GetNetworkUsageAsync()
    {
        try
        {
            // 简化实现：返回固定值
            await Task.Delay(1);
            return 0f;
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "获取网络使用率失败");
            return 0f;
        }
    }

    /// <summary>
    /// 获取详细系统信息
    /// </summary>
    public async Task<Dictionary<string, object>> GetDetailedSystemInfoAsync()
    {
        try
        {
            var info = new Dictionary<string, object>();

            // 操作系统信息
            info["OperatingSystem"] = Environment.OSVersion.ToString();
            info["MachineName"] = Environment.MachineName;
            info["UserName"] = Environment.UserName;
            info["ProcessorCount"] = Environment.ProcessorCount;

            return info;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取详细系统信息失败");
            return new Dictionary<string, object>();
        }
    }

    // 重复的GetGpuMemoryUsageAsync方法已移除

    // 重复的GetMemoryInfoAsync方法已移除

    private async Task<(long Total, long Available)> GetDiskInfoAsync()
    {
        try
        {
            var drives = DriveInfo.GetDrives();
            var systemDrive = drives.FirstOrDefault(d => d.IsReady && d.DriveType == DriveType.Fixed);

            if (systemDrive != null)
            {
                return (systemDrive.TotalSize, systemDrive.AvailableFreeSpace);
            }

            return (0, 0);
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "获取磁盘信息失败");
            return (0, 0);
        }
    }

    public void Dispose()
    {
        if (!_disposed)
        {
            StopMonitoring();
            _monitorTimer?.Dispose();
            _cpuCounter?.Dispose();
            _memoryCounter?.Dispose();
            _disposed = true;
        }
    }
}
